package com.qls.ali.biz.service.fz.impl;


import com.qls.ali.biz.data.util.FzUtil;
import com.qls.ali.biz.service.fz.Cache;
import com.qls.ali.biz.service.fz.HotelService;
import com.qls.ali.biz.service.fz.RoomService;
import com.qls.ali.biz.service.fz.RpService;
import com.qls.ali.biz.service.mybatis.*;
import com.qls.ali.model.vo.OpOurRateplanVo;
import com.qls.core.constant.Constant;
import com.qls.core.dto.HtDailyRoom;
import com.qls.core.dto.PushRatesBody;
import com.qls.core.entity.HtHotel;
import com.qls.core.entity.HtRoomType;
import com.qls.core.entity.HtSellRoom;
import com.qls.core.utils.DateUtils;
import com.qls.rabbitmq.SendMsg;
import com.qls.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;


/**
 * @author yunchao
 */
@Slf4j
@Service
public class HotelServiceImpl implements HotelService {

    @Autowired
    private OpHtlGroupService opHtlGroupService;

    @Autowired
    private HtHotelService htHotelService;

    @Autowired
    private HtPhysicalRoomService htPhysicalRoomService;

    @Autowired
    private RoomService roomService;

    @Autowired
    private RpService rpService;

    @Autowired
    private HtSellRoomService htSellRoomService;

    @Autowired
    private OpOurRateplanService opOurRateplanService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private SendMsg sendMsg;

    @Autowired
    private Cache cache;

    @Override
    public void pushAll(HtHotel htHotel, Integer storeId, String appKey, String secret, String session) {

        Long hotelCode = htHotel.getHotelCode();

        Integer partnerId = htHotel.getPartnerId();

        //推送酒店-----------------------------------------------------------------------------------------------------
        List<Long> hotelCodes = this.push(htHotel, storeId, appKey, secret, session);
        if (hotelCodes.isEmpty()) {
            return;
        }

        //推送物理房型-----------------------------------------------------------------------------------------------------
        Map<String, Object> hotelCodeMap = new HashMap<>();
        hotelCodeMap.put("hotel_code", hotelCode);
        List<HtRoomType> htPhysicalRooms = htPhysicalRoomService.listByMap(hotelCodeMap);
        if (htPhysicalRooms.isEmpty()) {
            return;
        }
        List<HtSellRoom> htLogicRooms = roomService.pushBatch(htPhysicalRooms, appKey, secret, session);
        if (htLogicRooms.isEmpty()) {
            return;
        }

        //推送rp----------------------------------------------------------------------------------------------------
        //查询自定义rp及 自定义rp的价格加幅
        List<OpOurRateplanVo> opOurRateplans = opOurRateplanService.getRatePlanPrice(storeId, hotelCode);
        if (opOurRateplans.isEmpty()) {
            log.warn("店铺id：{}，酒店id{}：请配置分组自定义价格政策和价格加幅", storeId, hotelCode);
            return;
        }

        /*//过滤rp
        List<HtLogicRoomEntity> htLogicRooms = new ArrayList<>();
        for (HtPhysicalRoomEntity htPhysicalRoom : htPhysicalRooms) {
            if (roomCodes.contains(htPhysicalRoom.getRoomCode())) {
                htLogicRooms.addAll(htPhysicalRoom.getHtLogicRoomEntities());
            }
        }*/

        // 推送
        Map<String, List<Integer>> stringListMap = rpService.pushBatch(htLogicRooms, storeId, appKey, secret, session, opOurRateplans, partnerId);

        if (stringListMap.isEmpty()) {
            return;
        }

        // 构造30天日期
        List<String> dates = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            dates.add(DateUtils.format(DateUtils.addDateDays(new Date(), i)));
        }
        // 推送价格的map
        Map<Long, List<HtDailyRoom>> map = new HashMap<>();
        for (String k : stringListMap.keySet()) {
            String[] newStr = k.split("_");
            String rpCode = newStr[0];
            map.put(Long.valueOf(rpCode), redisUtil.getRatesBatch(dates, rpCode));
        }
        // 推送价格 放入队列自动消费推送
        for (Long k : map.keySet()) {
            Map<String, Object> globFilterCache = cache.getGlobFilterCache(k.toString());
            List<Integer> storeIds = (List<Integer>) globFilterCache.get("storeIds");
            for (Integer id : storeIds) {
                PushRatesBody pushRatesBody = new PushRatesBody();
                pushRatesBody.setHtDailyRooms(map.get(k));
                pushRatesBody.setRpCode(k);
                sendMsg.execute(Constant.RabbitMq.RATES, id, pushRatesBody);
            }
        }

    }

    @Override
    public List<Long> push(HtHotel htHotelinfo, Integer storeId, String appKey, String secret, String session) {
        String ok = "xhotel_update_response";
        List<Long> hotelCodes = new ArrayList<>();
        String result = FzUtil.pushHotel(htHotelinfo, appKey, session, secret);
        if (!result.contains(ok)) {
            log.warn("{}：酒店推送失败，失败原因：{}", htHotelinfo.getHotelCode(), result);
            return hotelCodes;
        }
        Long hotelCode = htHotelinfo.getHotelCode();
        hotelCodes.add(hotelCode);
        // 更新数据库上架状态
        opHtlGroupService.updateIsUpByHotelIdAndStoreId(1, hotelCode, storeId);
        return hotelCodes;
    }

    @Override
    public void delAll(Long hotelCode, Integer storeId, String appKey, String secret, String session) {
        // 查询酒店是否上架到店铺
        Integer isUp = opHtlGroupService.getIsUpByStoreIdAndHotelId(storeId, hotelCode);
        if (Objects.isNull(isUp) || isUp.equals(0)) {
            return;
        }
        boolean flag = true;
        List<Long> longList = htSellRoomService.getRpCodesByHotelCode(hotelCode);
        for (Long rpCode : longList) {
            boolean flagRp = rpService.del(rpCode, null, storeId, appKey, secret, session);
            if (!flagRp) {
                flag = false;
            }
        }
        if (!flag) {
            return;
        }
        boolean flagHtl = this.del(hotelCode, storeId, appKey, secret, session);
        if (!flagHtl) {
            return;
        }
        // 更新酒店推送状态
        opHtlGroupService.updateIsUpByHotelIdAndStoreId(0, hotelCode, storeId);
    }

    @Override
    public boolean del(Long hotelCode, Integer storeId, String appKey, String secret, String session) {
        String ok = "xhotel_delete_response";
        String result = FzUtil.delHotel(hotelCode.toString(), appKey, session, secret);
        if (!result.contains(ok)) {
            log.warn("店铺id：{}，删除酒店失败，失败原因{}", storeId, result);
            return false;
        }
        return true;
    }


}
